package com.central.apps.service.impl;

import com.central.app.service.HandlerService;
import com.central.apps.dao.MaterialInventory.inventoryDao;
import com.central.apps.service.IInventoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class InventoryServiceImpl implements IInventoryService {

    @Autowired
    private HandlerService handlerService;
    @Autowired
    private inventoryDao inventoryDao;

    /**
     * 计算库存数量
     *
     * @param storeNum
     * @param itemNum
     */
    @Override
    public void calInvQuantity(String storeNum, String itemNum) {
        // 查询库存余量信息
        List<Map<String, Object>> list = handlerService.findBySql("select curbal from gq_invbalances where storenum = '" + storeNum + "' and itemnum = '" + itemNum + "'");

        if (CollectionUtils.isNotEmpty(list)) {
            // 计算库存余量
            Float totalQty = (float)0;
            for (Map<String, Object> map : list) {
                Float curbal = MapUtils.getFloat(map, "curbal");
//                int curbal = (int) map.get("curbal");
                totalQty = totalQty + curbal;
            }

            Float avblbalance = (float) 0;
            // 查询库存预留数量
            list = handlerService.findBySql("select reservedqty, isreorder, isgeneratepr, reorderminstock from gq_inventory where storenum = '" + storeNum + "' and itemnum = '" + itemNum + "'");

            if (CollectionUtils.isNotEmpty(list)) {
                Map<String, Object> map = list.get(0);
                Float reservedqty = MapUtils.getFloat(map, "reservedqty");
//                int reservedqty = (int) map.get("reservedqty");
                String isreorder = (String) map.get("isreorder");
                String isgeneratepr = (String) map.get("isgeneratepr");
//                int reorderminstock = (int) map.get("reorderminstock");
                Float reorderminstock = MapUtils.getFloat(map, "reorderminstock");
                avblbalance = totalQty - reservedqty;

                if (avblbalance < 0) {
                    avblbalance =(float) 0;
                }

                // 更新是否生成
                updInvAttr(isreorder, isgeneratepr, avblbalance, reorderminstock, storeNum, itemNum);

                // 更新库存余量/可用余量
                handlerService.updateBySql("update gq_inventory set curbaltotal = " + totalQty + ", avblbalance = " + avblbalance +
                        " where storenum = '" + storeNum + "' and itemnum = '" + itemNum + "'");
            }
        }
    }

    /**
     * 更新库存预留数量
     *
     * @param storeNum
     * @param itemNum
     * @param reverseQty
     */
    @Override
    public void updateInvReserveQty(String storeNum, String itemNum, int reverseQty) {
        // 查询库存余量信息
        List<Map<String, Object>> list = handlerService.findBySql("select curbaltotal, reservedqty, isreorder, isgeneratepr, reorderminstock from gq_inventory where storenum = '" + storeNum + "' and itemnum = '" + itemNum + "'");

        // 更新库存余量/可用余量
        Float avblbalance = (float)0;
        Float invReverseQty =(float) 0;
        if (CollectionUtils.isNotEmpty(list)) {
            Map<String, Object> map = list.get(0);
            Float totalQty = (float) map.get("curbaltotal");
            invReverseQty = (float) map.get("reservedqty");
            String isreorder = (String) map.get("isreorder");
            String isgeneratepr = (String) map.get("isgeneratepr");
            Float reorderminstock = (float) map.get("reorderminstock");

            invReverseQty = invReverseQty + reverseQty;
            avblbalance = totalQty - invReverseQty;

            if (avblbalance < 0) {
                avblbalance =(float) 0;
            }
            if (invReverseQty < 0) {
                invReverseQty = (float)0;
            }

            // 更新是否生成
            updInvAttr(isreorder, isgeneratepr, avblbalance, reorderminstock, storeNum, itemNum);

            // 更新预留数量/可用余量
            handlerService.updateBySql("update gq_inventory set reservedqty = " + invReverseQty + ", avblbalance = " + avblbalance +
                    " where storenum = '" + storeNum + "' and itemnum = '" + itemNum + "'");
        }
    }

    /**
     * 更新库存预留数量
     *
     * @param storeNum
     * @param itemNum
     * @param qty
     * @param isUpdate
     */
    @Override
    public void updateInvQty(String storeNum, String itemNum, int qty, boolean isUpdate) {
        // 查询库存信息
        List<Map<String, Object>> list = handlerService.findBySql("select curbaltotal, reservedqty, isreorder, isgeneratepr, reorderminstock from gq_inventory where storenum = '" + storeNum + "' and itemnum = '" + itemNum + "'");

        // 更新库存余量/可用余量
        if (CollectionUtils.isNotEmpty(list)) {
            Float avblbalance =(float) 0;
            Map<String, Object> map = list.get(0);
            Float curbaltotal = (float) map.get("curbaltotal");
            Float reservedqty = (float) map.get("reservedqty");
            String isreorder = (String) map.get("isreorder");
            String isgeneratepr = (String) map.get("isgeneratepr");
            Float reorderminstock = (float) map.get("reorderminstock");

            if (isUpdate) {
                reservedqty = reservedqty - qty;
            }

            curbaltotal = curbaltotal - qty;
            avblbalance = curbaltotal - reservedqty;

            if (curbaltotal < 0) {
                curbaltotal = (float)0;
            }
            if (reservedqty < 0) {
                reservedqty = (float)0;
            }
            if (avblbalance < 0) {
                avblbalance = (float)0;
            }

            // 更新是否生成
            updInvAttr(isreorder, isgeneratepr, avblbalance, reorderminstock, storeNum, itemNum);

            // 更新预留数量/可用余量/库存余量
            handlerService.updateBySql("update gq_inventory set reservedqty = " + reservedqty + ", avblbalance = " + avblbalance + ", curbaltotal = " + curbaltotal +
                    " where storenum = '" + storeNum + "' and itemnum = '" + itemNum + "'");
        }
    }

    /**
     * 修改库存成本
     * @param params
     * storenum  仓库编号
     * itemnum   物料编号
     * lotnum    批次
     * quantity  入库数量
     * outprice  入库价格
     */
    @Override
    public void updateInvcost(Map<String, Object> params) {
        //查标准成本
        String itemnum = MapUtils.getString(params, "itemnum"); //物料编码
        String standardcost = inventoryDao.getStandardcostByStorenum(itemnum); //物料标准成本
        params.put("stdcost", standardcost);

        //查平均成本
        String avgcost = inventoryDao.getAvgcostBySIB(params);
        //查余量
        Integer curbal = inventoryDao.getCurbalBySIBB(params);

        //修改库存平均价格  计算公式为（入库数量*入库价格+库存总数量*库存平均价）/入库数量+库存总数量
        Integer quantity = MapUtils.getInteger(params, "quantity");  //入库数量
        String outprice = MapUtils.getString(params, "outprice");    //入库价格
        DecimalFormat decimalFormat = new DecimalFormat("##0.00");
        BigDecimal outpriceBD = new BigDecimal(quantity);
        BigDecimal quantityBD = new BigDecimal(outprice);
        //入库数量*入库价格
        BigDecimal putSumPriceBD = outpriceBD.multiply(quantityBD);
        //库存总数量*库存平均价
        BigDecimal avgcostBD = new BigDecimal(avgcost == null ? "0" : avgcost);
        BigDecimal curbalBD = new BigDecimal(curbal);
        BigDecimal invcostSumPriceBD = curbalBD.multiply(avgcostBD);
        //（入库数量*入库价格+库存总数量*库存平均价）/入库数量+库存总数量

        if (StringUtils.isBlank(avgcost)) {
            //如果没有匹配的库存成本则新增
            Integer sumNum = quantity;
            BigDecimal sumNumBD = new BigDecimal(sumNum);
            BigDecimal newAvgcostBD = putSumPriceBD.add(invcostSumPriceBD).divide(sumNumBD, 2);
            String newAvgcost = decimalFormat.format(newAvgcostBD);

            params.put("avgcost", newAvgcost);
            params.put("lastcost", MapUtils.getString(params, "outprice"));
            inventoryDao.insertInvcost(params);
        }else {
            Integer sumNum = quantity + curbal;
            BigDecimal sumNumBD = new BigDecimal(sumNum);
            BigDecimal newAvgcostBD = putSumPriceBD.add(invcostSumPriceBD).divide(sumNumBD, 2);
            String newAvgcost = decimalFormat.format(newAvgcostBD);

            params.put("avgcost", newAvgcost);
            params.put("lastcost", MapUtils.getString(params, "outprice"));
            //修改记录
            inventoryDao.updateInvcost(params);
        }
    }

    /**
     * 更新库存重订购是否生成采购申请属性
     *
     * @param isreorder
     * @param isgeneratepr
     * @param avblbalance
     * @param reorderminstock
     * @param storenum
     * @param itemnum
     */
    private void updInvAttr(String isreorder, String isgeneratepr, Float avblbalance, Float reorderminstock, String storenum, String itemnum) {
        if ("1".equals(isreorder) && avblbalance > reorderminstock && "1".equals(isgeneratepr)) {
            handlerService.updateBySql("update gq_inventory set isgeneratepr = '0' where storenum = '" + storenum + "' and itemnum = '" + itemnum + "'");
        }
    }
}
